/**
 * 日    期：12-2-11
 */
package com.apes.oap.impl;

import com.apes.oap.RopRequest;
import com.apes.oap.RopRequestContext;
import com.apes.oap.ServiceMethodAdapter;
import com.apes.oap.ServiceMethodHandler;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.util.StringUtils;

import java.lang.reflect.InvocationTargetException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * <pre>
 * 通过该服务方法适配器调用目标的服务方法
 * </pre>
 *
 * @version 1.0
 */
public class AnnotationServiceMethodAdapter implements ServiceMethodAdapter {

    protected final Log logger = LogFactory.getLog(this.getClass());

    /**
     * 调用ROP服务方法
     *
     * @param ropRequest
     * @return
     */
    public Object invokeServiceMethod(RopRequest ropRequest) {
        try {
            RopRequestContext ropRequestContext = ropRequest.getRopRequestContext();
            // 分析上下文中的错误
            ServiceMethodHandler serviceMethodHandler = ropRequestContext.getServiceMethodHandler();
            if (serviceMethodHandler.isHandlerMethodWithParameter()) {
                return serviceMethodHandler.getHandlerMethod().invoke(serviceMethodHandler.getHandler(), ropRequest);
            } else {
                return serviceMethodHandler.getHandlerMethod().invoke(serviceMethodHandler.getHandler());
            }
        } catch (Throwable e) {
            throwOracleException(e);
            if (e instanceof InvocationTargetException) {
                InvocationTargetException inve = (InvocationTargetException) e;
                throw new RuntimeException(getThrowable(inve.getTargetException()));
            } else {
                throw new RuntimeException(getThrowable(e));
            }
        }
    }

    private static Throwable getThrowable(Throwable e) {
        Throwable throwable = e.getCause();
        if (throwable == null) return e;
        return getThrowable(throwable);
    }

    /**
     * 处理数据库异常消息
     **/
    private void throwOracleException(Throwable e) {
        String message = e.getMessage();
        if (e instanceof InvocationTargetException) {
            InvocationTargetException inve = (InvocationTargetException) e;
            message = inve.getTargetException().getMessage();
            if(StringUtils.isEmpty(message)) message = inve.getMessage();
        }
        message = getMessage(message);
        if (!StringUtils.isEmpty(message)) {
            e.printStackTrace();
            throw new RuntimeException(message);
        }
    }

    private String getMessage(String value) {
        if (value == null) return null;
        String regex = "ORA-\\d+[^;]*;";
        return getMessage(regex, value);
    }

    private String getMessage(String regex, String value) {
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(value);
        if (matcher.find()) {
            return matcher.group().trim();
        }
        return null;
    }

}
